package com.lzy.netty.websocket;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

/**
*  初始化器，channel注册后，会触发初始化方法，完成业务逻辑
*/
public class WSServerinitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {

        // 通过SocketChannel获取ChannelPipeline
        ChannelPipeline channelPipeline = socketChannel.pipeline();

        /**
         * 通过管道，添加自定义的handler，处理业务逻辑
         */

        // httpServerCodec 是由netty提供的助手类，类似于拦截器
        // 当请求到服务器，会经过HttpServerCodec解码器
        // websocket 基于http协议，所以要有http解码器
        channelPipeline.addLast(new HttpServerCodec());

        // 添加对大数据流的支持
        channelPipeline.addLast(new ChunkedWriteHandler());

        // 对httpMessage进行聚合，聚合成FullHttpRequest或FullHttpResponse
        // 几乎在netty的编程中，都会用到此handler
        channelPipeline.addLast(new HttpObjectAggregator(1024 * 64));

        // =============================== 以上是支持http协议请求的逻辑处理 ===================================


        // =============================== 增加心跳支持 start ===================================
        channelPipeline.addLast(new IdleStateHandler(8,
                                                    10,
                                                    30 * 60));
        // 用户事件触发器
        channelPipeline.addLast(new HeartBeatHandler());

        /**
         * websocket 服务处理的协议，用于指定给客户端连接时访问的路由 -- WebSocketServerProtocolHandler，
         * 处理握手升级协议，将http升级为websocket协议
         * 对于WebSocket来说，数据都是frame，所以，数据在传输过程中，都是frame，不同的数据类型所对应的frame也不同
         */
        channelPipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        // 添加自定义的助手类
        channelPipeline.addLast(new ChatHandler());
    }
}
